package com.example.utils;

import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;

public class ECCUtil {
    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }
    public static String priToPub (String privateKeyHex) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
        BigInteger privateKeyInt = new BigInteger(privateKeyHex, 16);
        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256k1");
        ECPrivateKeySpec privateKeySpec = new ECPrivateKeySpec(privateKeyInt, ecSpec);
        KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
        PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

        // 获取对应的公钥对象
        ECPoint Q = ecSpec.getG().multiply(privateKeyInt);
        byte[] publicKeyBytes = Q.getEncoded(false);
        KeySpec publicKeySpec = new ECPublicKeySpec(Q, ecSpec);
        PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

        // 公钥对象转换为十六进制字符串
        return Hex.toHexString(publicKeyBytes);
    }

    public static byte[] generateSharedSecret(String privateKeyHex, String publicKeyHex) throws Exception {
        // 获取SECP256k1曲线参数
        ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256k1");

        // 转换发送者的私钥和接收者的公钥
        BigInteger senderPrivateKeyInt = new BigInteger(privateKeyHex, 16);
        ECPoint receiverPublicKeyPoint = ecSpec.getCurve().decodePoint(Hex.decode(publicKeyHex));

        // 创建发送者私钥对象
        ECPrivateKeySpec senderPrivateKeySpec = new ECPrivateKeySpec(senderPrivateKeyInt, ecSpec);
        KeyFactory keyFactory = KeyFactory.getInstance("ECDH", "BC");
        PrivateKey senderPrivateKey = keyFactory.generatePrivate(senderPrivateKeySpec);

        // 创建接收者公钥对象
        ECPublicKeySpec receiverPublicKeySpec = new ECPublicKeySpec(receiverPublicKeyPoint, ecSpec);
        PublicKey receiverPublicKey = keyFactory.generatePublic(receiverPublicKeySpec);

        // 生成发送者共享秘密
        KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("ECDH", "BC");
        senderKeyAgreement.init(senderPrivateKey);
        senderKeyAgreement.doPhase(receiverPublicKey, true);
        byte[] sharedSecret = senderKeyAgreement.generateSecret();

        // 使用SHA-256哈希生成发送者共享秘密
        MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
        byte[] sharedKey = sha256.digest(sharedSecret);

        // 打印发送者共享秘密
        // System.out.println("Sender's Shared Key (Base64): " + Base64.getEncoder().encodeToString(sharedKey));

        return sharedKey;
    }
    public static String encryptMessage(String message, byte[] key) throws Exception {
        // 创建AES密钥对象
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");

        // 生成随机IV
        byte[] iv = new byte[16];
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(iv);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        // 创建AES加密Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);

        // 加密消息
        byte[] ciphertext = cipher.doFinal(message.getBytes("UTF-8"));

        // 返回IV和密文的组合
        byte[] encryptedMessage = new byte[iv.length + ciphertext.length];
        System.arraycopy(iv, 0, encryptedMessage, 0, iv.length);
        System.arraycopy(ciphertext, 0, encryptedMessage, iv.length, ciphertext.length);
        return Base64.getEncoder().encodeToString(encryptedMessage);
    }

    public static String decryptMessage(String encryptedMessageBase64, byte[] key) throws Exception {
        byte[] encryptedMessage = Base64.getDecoder().decode(encryptedMessageBase64);
        // 创建AES密钥对象
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");

        // 提取IV
        byte[] iv = Arrays.copyOfRange(encryptedMessage, 0, 16);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        // 提取密文
        byte[] ciphertext = Arrays.copyOfRange(encryptedMessage, 16, encryptedMessage.length);

        // 创建AES解密Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);

        // 解密消息
        byte[] plaintext = cipher.doFinal(ciphertext);
        return new String(plaintext, "UTF-8");
    }
}
